package com.rocsun.web.interceptor;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.rocsun.auth.AuthUser;
import com.rocsun.auth.LoginUser;
import com.rocsun.constant.CommonConstant;
import com.rocsun.login.CurrentUserContextHolder;
import com.rocsun.web.utils.JwtUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

/**
 * @program: rocsun-scali
 * @description:
 * @author: yx.guo
 * @create: 2025-11-08 19:44
 **/
@Component
public class AuthHandlerInterceptor implements HandlerInterceptor {

    private static final Log log = LogFactory.get();

    @Autowired
    private JwtUtil jwtUtil;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("请求URL: {}, 方法: {}, Handler: {}", request.getRequestURI(), request.getMethod(), handler.getClass().getSimpleName());


        // 如果不是映射到方法直接通过，可以访问资源
        if(!(handler instanceof HandlerMethod)){
            return true;
        }

        // 放行OPTIONS请求
        String method = request.getMethod();
        String requestUri = request.getRequestURI();
        if ("OPTIONS".equalsIgnoreCase(method)) {
            log.info("拦截器 - 放行OPTIONS预检请求: {}", requestUri);
            return true;
        }


        // 为空就返回错误
        String myToken = request.getHeader("Authorization");
        if (ObjectUtil.isEmpty(myToken) || StrUtil.isBlank(myToken) || !myToken.startsWith(CommonConstant.TOKEN_PREFIX)) {
            log.warn("Token缺失或格式错误: {}", myToken);
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.getWriter().write("{\"code\":401,\"message\":\"Token缺失或格式错误\"}");
            return false;
        }
        log.info("===========token: " + myToken);

        try {
            // 真实token
            String token = jwtUtil.getRelToken(myToken);

            // 验证token和密钥是否一致
            boolean verify = jwtUtil.verify(token);
            if (!verify) {
                log.warn("Token验证失败");
                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                response.getWriter().write("{\"code\":401,\"message\":\"Token验证失败\"}");
                return false;
            }

            AuthUser authUser = jwtUtil.parseToken(token);
            // 记录当前用户
            CurrentUserContextHolder.setCurrentUser(LoginUser.builder()
                    .userName(authUser.getUserName())
                    .nickName(authUser.getNickName())
                    .roles(authUser.getRoles())
                    .build());

            return true;
        } catch (Exception e) {
            log.error("Token处理异常", e);
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.getWriter().write("{\"code\":401,\"message\":\"Token处理异常\"}");
            return false;
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        CurrentUserContextHolder.clearCurrentUser();
    }
}
